package com.yb.login.center.template;

import com.alibaba.fastjson2.JSONObject;
import com.yb.auth.core.bean.SysUser;
import com.yb.auth.core.constant.LoginConstant;
import com.yb.auth.core.util.SecurityUtils;
import com.yb.core.bean.Resp;
import com.yb.core.constant.HttpConstant;
import com.yb.core.constant.RedisConstant;
import com.yb.core.util.JwtTokenUtil;
import com.yb.core.util.RedisUtil;
import com.yb.login.center.vo.LoginVo;
import com.yb.login.center.vo.UserLoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.util.StringUtils;

import java.util.Objects;
import java.util.UUID;

@Slf4j
public abstract class AbstractUserServiceTemplate {
    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    JwtTokenUtil jwtTokenUtil;

    @Autowired
    RedisUtil redisUtil;
    protected abstract Authentication loadAuthentication(LoginVo loginVo);

    protected abstract  SysUser loadSysUser(Authentication authentication);

    protected abstract LoginConstant.LoginType getLoginType();

    protected  void onSuccess(){

    }

    protected Resp successLogin(Authentication authenticate){
        SysUser sysUser = loadSysUser(authenticate);

        sysUser.setLoginType(getLoginType());

        String token = "";
        String exToken = redisUtil.get(String.format(RedisConstant.AUTH_USER_KEY, sysUser.getUsername(), sysUser.getUserId()));
        if(StringUtils.hasText(exToken)){
            token=exToken;
        }else{
            token= UUID.randomUUID().toString().replace("-", "");
            redisUtil.set(String.format(RedisConstant.AUTH_USER_KEY,sysUser.getUsername(),sysUser.getUserId()), token);
        }
        redisUtil.set(String.format(RedisConstant.AUTH_TOKEN_KEY,token), JSONObject.toJSONString(sysUser));

        //如果登陆成功，则将用户信息放入redis，生成访问token
        UserLoginVo respVo = new UserLoginVo();
        respVo.setUserId(sysUser.getUserId());
        respVo.setUsername(sysUser.getUsername());
        respVo.setToken(token);
        this.onSuccess();
        return Resp.ok().data(respVo);
    }

    public Resp login(LoginVo loginVo) {
        Authentication authenticationToken = loadAuthentication(loginVo);
        Authentication authenticate=null;
        try {
            authenticate = authenticationManager.authenticate(authenticationToken);
        }catch (Exception e){
            log.error("auth error:{}",e);
            throw  e;
        }


        if(Objects.isNull(authenticate)){
            return Resp.ok(HttpConstant.Response.INVALID_USER);
        }

        SecurityUtils.setAuthentication(authenticate);

        return successLogin(authenticate);

    }
}
